// Created by lihengliu on 2023/2/24.
//
#include <jni.h>
#include <string>
#include<android/log.h>
#include "util/jni_helper.h"

#define LOG_TAG "OTHER_LIB"
#define LOG_H(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)

using namespace std;
using namespace clu;

//全局JavaVM
JavaVM *newVm;

//jstring转cstring
//char* jstr2cstr(JNIEnv *env,jstring content) {
//    char *result = nullptr;
//    jclass clazz = env->FindClass("java/lang/String");
//    jstring str_encode = env->NewStringUTF("UTF-8");
//    jmethodID method_get_bytes = env->GetMethodID(clazz, "getBytes", "(Ljava/lang/String;)[B");
//    auto byte_array = (jbyteArray)env->CallObjectMethod(content, method_get_bytes, str_encode);
//    jsize byte_array_length = env->GetArrayLength(byte_array);
//    jbyte *byte_array_bytes = env->GetByteArrayElements(byte_array, JNI_FALSE);
//    if (byte_array_length > 0) {
//        result = (char *) malloc(byte_array_length + 1);
//        memcpy(result, byte_array_bytes, byte_array_length);
//        result[byte_array_length] = 0;
//    }
//    env->ReleaseByteArrayElements(byte_array, byte_array_bytes, 0);
//    return result;
//}


//对应JNI的方法名(可自定义)
jstring testDynamicRegisterMethod(JNIEnv *env,jobject thiz) {
    std::string value = "testDynamicRegisterMethod";
    return env->NewStringUTF(value.c_str());
}

jstring operateStringFromJNI(JNIEnv *env, jobject thiz, jstring value) {
    const char *name = "basketball";

    //strchr(const char* const s __pass_object_size, int c) 返回c(包含c)之后的所有内容
    //const char* p = strchr(name, 't');
    //LOG_H("%s\n",p);

    //strstr(const char* h, const char* n) 从h中查找n,若存在则放回n以及h中n之后的内容,否则返回NULL
    //const char *name1 = "basketball";
    //const char *name2 = "tball";
    //const char* p0 = strstr(name2, name1);
    //LOG_H("%s\n",p0);

    //int strcmp(const char* __lhs, const char* __rhs) 比较两个字符串的大小  > 0 则 前者大于后者  == 0 则两者相等  否则前者小于后者
    //const char *name1 = "basketball";
    //const char *name2 = "ball";
    //int result = strcmp(name1, name2);
    //LOG_H("%d\n",result);

    //char* strcpy(char* const dst __pass_object_size, const char* src)  src赋值给dst
    //std::string c0 = "aa12";
    //std::string c1 = "67890ghjkl";
    //char *name1 = jstr2cstr(env, env->NewStringUTF(c0.c_str()));
    //char *name2 = jstr2cstr(env, env->NewStringUTF(c1.c_str()));

    //std::string c2 = "pick00";
    //char* const ch = jstr2cstr(env, env->NewStringUTF(c0.c_str()));
    //const char *result = strcpy(ch, name1);
    //LOG_H("%s\n",result);

    return env->NewStringUTF(name);
}


const JNINativeMethod methods[] = {
        {"dynamicRegisterMethod", "()Ljava/lang/String;", (jstring *) testDynamicRegisterMethod},
        {"operateStringFromJNI", "(Ljava/lang/String;)Ljava/lang/String;", (jstring *) operateStringFromJNI},
};

/*
 * 系统提供的动态注册JNI方法结构体
 * typedef struct {
      const char* name;  //方法名
      const char* signature;//方法签名
      void* fnPtr;//函数指针
   } JNINativeMethod;
 *
 */

extern "C" JNIEXPORT jstring JNICALL Java_com_hengfoxwolf_jnidemo_MainActivity_stringFromJNIInOtherLib(
        JNIEnv* env,
        jobject thiz) {
    std::string hello = "Hello from C++ in other lib";

//    bool ret = JniHelper::startJavaVMAttachCurrentThread();

    JniMethodInfo t;
    if (JniHelper::getMethodInfo(t,
                                 "com/hengfoxwolf/jnidemo/MainActivity",
                                 "doTest",
                                 "()V")) {
        t.env->CallVoidMethod(thiz, t.methodID);
    }

    if (t.classID != nullptr) {
        t.env->DeleteLocalRef(t.classID);
    }

//    if (ret) {
//        JniHelper::stopJavaVMAttachCurrentThread();
//    }

    return env->NewStringUTF(hello.c_str());
}

//动态注册JNI方法--系统方法(需要重写此方法)
jint JNI_OnLoad(JavaVM *vm, void *args) {

    JniHelper::setJavaVM(vm);

    newVm = vm;

    JNIEnv *env = nullptr;
    jint value = vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
    if (JNI_OK != value) {
        return -1;
    }

    jclass clazz = env->FindClass("com/hengfoxwolf/jnidemo/MainActivity");

    //动态注册
    env->RegisterNatives(clazz, methods, sizeof methods / sizeof(JNINativeMethod));

    //返回版本号
    return JNI_VERSION_1_6;
}